package com.zlcx.tz.live.common.interceptor;

import com.alibaba.fastjson.JSON;
import com.zlcx.tz.live.common.annotation.AuthSig;
import com.zlcx.tz.live.exception.BusinessException;
import com.zlcx.tz.live.utils.SignUtil;
import io.swagger.models.HttpMethod;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * sig校验
 * @author zl
 * @date 2018/1/9 17:05
 */

@Component
@Slf4j
public class SignInterceptor extends HandlerInterceptorAdapter {

    @Value("${shangde.sign.secret}")
    String secret;

    @Value("${shangde.sign.testSecret}")
    String testSecret;

    @Value("${sign.devMode}")
    boolean signDevMode;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse httpServletResponse, Object o) throws Exception {

        if(signDevMode){
            return true;
        }

        if(HttpMethod.OPTIONS.toString().equalsIgnoreCase(request.getMethod())){
            return true;
        }

        AuthSig annotation;
        if(o instanceof HandlerMethod) {
            annotation = ((HandlerMethod) o).getMethodAnnotation(AuthSig.class);
        }else{
            return true;
        }

        //如果没有@AuthSig注解，则不验证sig
        if(annotation == null){
            return true;
        }

        String sign = request.getHeader("sig");

        if (testSecret.equalsIgnoreCase(sign)) {
            return true;
        }


        Map<String, String[]> requestParams =requestToMapObject(request);
        boolean checkSign = SignUtil.verifySign(secret, sign, requestParams);
        if (checkSign) {
            return true;
        }else{
            Map<String, String> heads = new HashMap<>(10);
            Enumeration<String> headNames = request.getHeaderNames();
            while (headNames.hasMoreElements()) {
                String name = headNames.nextElement();
                String value = request.getParameter(name);
                if(StringUtils.isNotBlank(value)){
                    heads.put(name, value);
                }
            }

            log.info("[SignInterceptor]- {} method ,uri = 【{}】 ,localSig = 【{}】,heads = 【{}】,params = 【{}】", request.getMethod(),request.getRequestURI(),SignUtil.sign(secret, requestParams), JSON.toJSONString(heads), JSON.toJSONString(requestParams));

            throw new BusinessException("签名错误");
        }

    }


    /**
     * 判断GET请求的签名
     * @param request
     * @return
     */
    private HashMap<String, String []> requestToMapObject(HttpServletRequest request) {

        HashMap<String, String []> parameterMap = new HashMap<String, String []>();
        Enumeration<String> names = request.getParameterNames();
        if (names != null) {
            Collections.list(names).stream().filter(name -> name != null).forEach(name -> {
                String value = request.getParameter(name);
                if(StringUtils.isNotEmpty(value)){
                    parameterMap.put(name.toString(), new String [] {request.getParameter(name.toString())});
                }else{
                    String[] values = request.getParameterValues(name);
                    parameterMap.put(name.toString(), values);
                }
            });
        }
        return parameterMap;
    }
}
